package com.xiehua.task.utils;

import com.xiehua.task.annotation.FixedTaskExecutor;
import com.xiehua.task.annotation.Executor;
import com.xiehua.task.annotation.Task;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class ScanUtil {

    /**
     * 说明:扫描指定的包
     * @param packageName
     * @return list
     * **/
    public static List<Class<?>> scan(String packageName) throws IOException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        PathMatchingResourcePatternResolver reolver = new PathMatchingResourcePatternResolver(classLoader);
        String packageSearchPath = PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + packageName.replace(".", "/") + "/**/*.class";
        Resource[] resources = reolver.getResources(packageSearchPath);
        if(resources.length < 1) return Collections.emptyList();
        return Arrays.asList(resources).stream().map(s ->{
            try {
                return classLoader.loadClass(packageName + '.' + s.getFilename().replace(".class", ""));
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                return null;
            }
        }).filter(t -> t != null).collect(Collectors.toList());
    }

    /**
     * 说明:从class中过滤指定指定的注解
     * @param list
     * @param annotation
     * @return list
     * **/
    public static List<Class<?>> getClassWithAnnotation(List<Class<?>> list,Class<? extends Annotation> annotation){
        return list.stream().filter(s ->s.isAnnotationPresent(annotation)).collect(Collectors.toList());
    }

    /**
     * 说明:从class中过滤指定指定的注解
     * @param list
     * @return list
     * **/
    public static List<FixedTaskExecutor> getFixedTaskExecutor(List<Class<?>> list){
        return list.stream().map(s ->{
            FixedTaskExecutor t = new FixedTaskExecutor();
            t.setClassName(s.getName());
            t.setClassz(s);
            t.setTopic(s.getAnnotation(Task.class).topic());
            List<FixedTaskExecutor.TaskExecutor> executors = Arrays.asList(s.getMethods()).stream().filter(m -> m.isAnnotationPresent(Executor.class)).map(n ->{
                FixedTaskExecutor.TaskExecutor e = new FixedTaskExecutor.TaskExecutor();
                Executor executor = n.getAnnotation(Executor.class);
                e.setName(n.getName());
                e.setMethod(n);
                e.setCron(executor.cron());
                return e;
            }).collect(Collectors.toList());
            t.setExecutors(executors);
            return t;
        }).collect(Collectors.toList());
    }


}
